import { Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Store } from '@ngxs/store';
import { SystemAction } from '../../store';
import { DemoAction, DemoSelector } from '../../store/demo';
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
import * as _ from 'lodash';
import { HotkeysService } from '@ngneat/hotkeys';
import { debounceTime, Subject } from 'rxjs';

@Component({
  selector: 'app-demo',
  templateUrl: './demo.component.html',
  styleUrls: ['./demo.component.scss'],
})
export class DemoComponent implements OnInit, OnDestroy {
  @AutoUnsubscribe() current$ = this.store.select(DemoSelector.current);
  searchText = '';
  list: any = [];
  sort: string | null = null;

  @ViewChild('searchRef') searchRef!: ElementRef;
  search$ = new Subject<any>();

  hotkeys: { keys: string, callFn: any }[];

  constructor(
      private http: HttpClient,
      private store: Store,
      private hotkey: HotkeysService,
  ) {
    this.hotkeys = [
      {keys: 'control.n', callFn: this.newEditDemo.bind(this)},
      {keys: 'alt.n', callFn: this.newEditDemo.bind(this)},
      {keys: 'control.k', callFn: this.focusOnSearchInput.bind(this)},
      {keys: 'alt.k', callFn: this.focusOnSearchInput.bind(this)},
    ];
  }

  ngOnInit(): void {
    this.store.select(DemoSelector.current).subscribe(() => {
      this.search();
    });
    this.hotkeys.forEach(s => this.hotkey.addShortcut({keys: s.keys, preventDefault: true}).subscribe(s.callFn));
    this.search$.pipe(debounceTime(500)).subscribe(() => this.search());
  }

  ngOnDestroy(): void {
    this.hotkeys.forEach(s => this.hotkey.removeShortcuts(s.keys));
  }

  focusOnSearchInput() {
    this.searchRef.nativeElement.focus();
  };

  copy(text: string) {
    this.store.dispatch(new SystemAction.Copy(text));
  }

  jump(url: string) {
    this.store.dispatch(new SystemAction.Jump(url));
  }

  edit(data: any) {
    this.store.dispatch(new DemoAction.EditDemo(data));
  }

  newEditDemo() {
    this.store.dispatch(new DemoAction.EditDemoNew());
  };

  delete(data: any) {
    this.store.dispatch(new DemoAction.Delete(data));
  }

  search() {
    let list = this.store.selectSnapshot(DemoSelector.current);
    if (this.searchText.length === 0 || this.searchText.trim().length === 0) {
      this.list = list;
    } else {
      let split = this.searchText.split(' ');
      this.list = _.filter(list, (s: any) => !!_.find(split,
          j => (!!s.name && s.name.toLowerCase().indexOf(j.toLowerCase()) !== -1)
              || (!!s.url && s.url.toLowerCase().indexOf(j.toLowerCase()) !== -1)
              || (!!s.git && s.git.toLowerCase().indexOf(j.toLowerCase()) !== -1),
      ));
    }
    this.changeOrder();
  }

  changeOrderFn($event: string | null) {
    this.sort = $event;
    this.changeOrder();
  }

  changeOrder() {
    if ('ascend' === this.sort) {
      let list = this.list;
      list = _.sortBy(list, s => s.name);
      this.list = list;
    } else if ('descend' === this.sort) {
      let list = this.list;
      list = _.sortBy(list, s => s.name);
      list = _.reverse(list);
      this.list = list;
    }
  }
}
